﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using System.Device.Location;
using Microsoft.Phone.Controls.Maps;
using Microsoft.Phone.Shell;
using Microsoft.Phone.Controls.Maps.Platform;
using System.Diagnostics;
using System.Windows.Media.Imaging;
using Microsoft.Xna.Framework.Input.Touch;
using System.Windows.Threading;

namespace TransportMe
{
    public partial class Home : PhoneApplicationPage
    {
        public GeoCoordinateWatcher watcher;
        private FakeGps gps = new FakeGps();
        private ApplicationBarIconButton btnSettings;
        private Pushpin pinStart;
        private Pushpin pinEnd;
        private int numberOfPins = 0;
        private DispatcherTimer dt;
        public int cnt = 0;

        public Home()
        {
            InitializeComponent();

            ApplicationBar = new ApplicationBar();
            ApplicationBar.IsVisible = true;
            btnSettings = new ApplicationBarIconButton(new Uri("/appbar.feature.settings.rest.png", UriKind.Relative));
            btnSettings.Text = "Settings";
            btnSettings.Click += new EventHandler(btnSettings_Click);

            ApplicationBar.Buttons.Add(btnSettings);

            pinStart = new Pushpin();
            pinEnd = new Pushpin();
            pinStart.Content = "Start";
            pinEnd.Content = "End";

            TouchPanel.EnabledGestures = GestureType.Hold;
        }

        private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
        {
            CallLocationService();
        }

        public void CallLocationService()
        {
            // The watcher variable was previously declared as type GeoCoordinateWatcher.
            // gps.Start();

            if (watcher == null)
            {
                //watcher = new GeoCoordinateWatcher(GeoPositionAccuracy.High);
                //watcher.MovementThreshold = App.IsolatedStorageCacheManager<double>.Retrieve("thresholdSlider.xml"); // use MovementThreshold to ignore noise in the signal
                //watcher.StatusChanged += new EventHandler<GeoPositionStatusChangedEventArgs>(watcher_StatusChanged);
                //watcher.PositionChanged += new EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>(watcher_PositionChanged);
            }
            //watcher.Start();

            GeoCoordinate gc;
            switch (numberOfPins)
            {
                case 0:
                    App.L.Latitude = 1.297036; // queen st
                    App.L.Longitude = 103.851407;
                    gc = new GeoCoordinate(App.L.Latitude, App.L.Longitude);

                    map.SetView(gc, 17.5);
                    break;
                case 1:
                    App.L.Latitude = 1.331157; // bedok ave 3
                    App.L.Longitude = 103.932853;
                    gc = new GeoCoordinate(App.L.Latitude, App.L.Longitude);

                    map.SetView(gc, 17.5);
                    break;
                case 2:
                    App.L.Latitude = 1.354955; // millennia institute
                    App.L.Longitude = 103.736435;
                    
                    gc = new GeoCoordinate(App.L.Latitude, App.L.Longitude);

                    map.SetView(gc, 17.5);
                    break;
            }
        }

        public void CallLocationServiceAndPlacePin()
        {
            GeoCoordinate gc;
            switch (numberOfPins)
            {
                case 0:
                    CallLocationService();

                    gc = new GeoCoordinate(App.L.Latitude, App.L.Longitude);
                    pinStart.Location = gc;
                    map.Children.Add(pinStart);
                    numberOfPins++;

                    break;
                case 1:
                    CallLocationService();

                    gc = new GeoCoordinate(App.L.Latitude, App.L.Longitude);
                    pinEnd.Location = gc;
                    map.Children.Add(pinEnd);
                    numberOfPins++;

                    break;
                case 2:
                    CallLocationService();

                    if (MessageBox.Show("Change end point", "End", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
                    {
                        map.Children.Remove(pinEnd);
                        gc = new GeoCoordinate(App.L.Latitude, App.L.Longitude);
                        pinEnd.Location = gc;
                        map.Children.Add(pinEnd);
                    }

                    break;
            }
        }

        void watcher_PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)
        {
            //Deployment.Current.Dispatcher.BeginInvoke(() =>
            //{
            //SetMapLocation(e.Position.Location.Latitude, e.Position.Location.Longitude);
            App.L = e.Position.Location;

            GeoCoordinate gc = new GeoCoordinate(App.L.Latitude, App.L.Longitude);
            map.SetView(gc, 10);

            watcher.Stop();
            //watcher = null;
            //});

        }

        void watcher_StatusChanged(object sender, GeoPositionStatusChangedEventArgs e)
        {
            switch (e.Status)
            {
                case GeoPositionStatus.Disabled:
                    // The Location Service is disabled or unsupported.
                    // Check to see if the user has disabled the Location Service.
                    if (watcher.Permission == GeoPositionPermission.Denied)
                    {
                        // The user has disabled the Location Service on their device.
                        //statusTextBlock.Text = "you have this application access to location.";
                        MessageBox.Show("Your Location Service is disabled or unsupported. \n\nYou can enable it by exiting from this app and turning it on in your phone Settings page");
                    }
                    break;

                case GeoPositionStatus.Initializing:
                    // The Location Service is initializing.
                    // Disable the Start Location button.
                    //startLocationButton.IsEnabled = false;
                    //progressBar1.Visibility = System.Windows.Visibility.Visible;
                    //MessageBox.Show("Watcher initializing");
                    break;

                case GeoPositionStatus.NoData:
                    // The Location Service is working, but it cannot get location data.
                    // Alert the user and enable the Stop Location button.
                    //statusTextBlock.Text = "location data is not available.";
                    //stopLocationButton.IsEnabled = true;
                    //MessageBox.Show("Watcher no data");
                    // CHRIS: Happens briefly on initial stages of getting location
                    //if (!loadNearbylist)
                    //{
                        //MessageBox.Show("Your Location service is available but cannot get location data");
                        //mainPageStatusTextBlock.Text = "";
                        //checkBoxLocation.IsChecked = false;
                    //}
                    break;

                //called everytime watcher is restarted
                case GeoPositionStatus.Ready:
                    // The Location Service is working and is receiving location data.
                    // Show the current position and enable the Stop Location button.
                    //statusTextBlock.Text = "location data is available.";
                    //stopLocationButton.IsEnabled = true;
                    //if (progressBar1.Visibility == System.Windows.Visibility.Visible)
                    //{
                    //    progressBar1.Visibility = System.Windows.Visibility.Collapsed;
                    //};
                    //MessageBox.Show("Hello");
                    //SetupPushNotification();
                    //MessageBox.Show("Watcher ready");
                    break;
            }
        }

        private void btnCalc_Click(object sender, RoutedEventArgs e)
        {
            btnCalc.Content = "End";
        }

        private void btnSettings_Click(object sender, EventArgs e)
        {
            string page = "0";
            //if (App.FromPage == 0 || App.FromPage == 1) page = "0";
            //else if (App.FromPage == 2) page = "1";
            NavigationService.Navigate(new Uri("/Settings.xaml?p=" + page, UriKind.Relative));
        }

        private void btnFind_Click(object sender, RoutedEventArgs e)
        {
            CallLocationService();
        }

        private void PlantPin(Pushpin p, Location l)
        {
            p.Location = l;
            map.Children.Add(p);
        }

        private void map_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            //Debug.WriteLine("Hi");
                //Change the Clickmode to Press, add a dispatchTimer and a method to catch the press event which begins the timer, a counter for your timer ticks and a method call inside the tick if you hit your counter criteria.  But note that the press event will be triggered in a “press and release” scenario as well
        }

        private void imgStart_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (numberOfPins != 2)
            {
                CallLocationServiceAndPlacePin();
            }
            switch (numberOfPins)
            {
                case 1:
                    imgStart.Source = new BitmapImage(new Uri("Images/Pushpin-End.png", UriKind.Relative));
                    break;
                case 2:
                    imgStart.Source = new BitmapImage(new Uri("Images/Calc.png", UriKind.Relative));
                    break;
            }
        }

        private void imgStart_ImageFailed(object sender, ExceptionRoutedEventArgs e)
        {
            // do nothing
        }

        //private void StartHoldTimer()
        //{
        //    dt = new DispatcherTimer();
        //    dt.Interval = new TimeSpan(0, 0, 0, 0, 500);// 500 Milliseconds
        //    dt.Tick += new EventHandler(dt_Tick);
        //    dt.Start();
        //}

        private void dt_Tick(object sender, EventArgs e)
        {
            if (cnt == 3) // 500 ms * 4 == 2 seconds
            {
                cnt = 0;
                GetGesture();
                // disable all events
                TouchPanel.EnabledGestures = GestureType.None;
                // stop the hold timer
                StopHoldTimer();
                Debug.WriteLine("Good job!");
            }
            cnt++;
        }

        public void StartHoldTimer()
        {
            dt = new System.Windows.Threading.DispatcherTimer();
            dt.Interval = new TimeSpan(0, 0, 0, 0, 500);// 500 Milliseconds
            dt.Tick += new EventHandler(dt_Tick);
            dt.Start();
        }

        private void StopHoldTimer()
        {
            dt.Stop();
            cnt = 0;
        }

        private void GetGesture()
        {
            if (TouchPanel.IsGestureAvailable)
            {
                GestureSample gs = TouchPanel.ReadGesture();
                if (gs.GestureType == GestureType.Hold)
                {
                    string gestureString = string.Format("{0}: {1}", gs.GestureType, gs.Position);
                    // Tap and Hold detected, report position
                    Debug.WriteLine(gestureString);
                }
            }
        }

        private void map_ManipulationStarted(object sender, ManipulationStartedEventArgs e)
        {
            // specify what events the XNA gesture recognizer will look out for
            TouchPanel.EnabledGestures = GestureType.Hold;
            // start the hold timer
            StartHoldTimer();
        }

        private void map_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
        {
            // disable all events
            TouchPanel.EnabledGestures = GestureType.None;
            // stop the hold timer
            StopHoldTimer();
        }

        private void map_Hold(object sender, System.Windows.Input.GestureEventArgs e)
        {
            switch (numberOfPins)
            {
                case 0:
                    if (MessageBox.Show("Add start point", "Start", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
                    {
                        var position = e.GetPosition(map);
                        var location = map.ViewportPointToLocation(position);
                        pinStart.Location = location;
                        map.Children.Add(pinStart);
                        numberOfPins++;
                    }
                    break;
                case 1:
                    if (MessageBox.Show("Add end point", "End", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
                    {
                        var position = e.GetPosition(map);
                        var location = map.ViewportPointToLocation(position);
                        pinEnd.Location = location;
                        map.Children.Add(pinEnd);
                        numberOfPins++;
                    }
                    break;
                case 2:
                    if (MessageBox.Show("Change end point?", "End", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
                    {
                        map.Children.Remove(pinEnd);
                        var position = e.GetPosition(map);
                        var location = map.ViewportPointToLocation(position);
                        pinEnd.Location = location;
                        map.Children.Add(pinEnd);
                    }
                    break;
            }
        }
    }
}
